#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define fast \
ios_base::sync_with_stdio(0); \
cin.tie(0); \
cout.tie(0);
int n,l;
vector<vector<int>> adj;
int timer,sz;
vector<int> tin,tout,dep,a,tree;
vector<vector<int>> up;
void dfs1(int v, int p)
{
tin[v] = ++timer;
up[v][0] = p;
for (int i = 1; i <= l; ++i)
up[v][i] = up[up[v][i-1]][i-1];
for (int u : adj[v]) {
if (u != p)
dfs1(u, v);
}
tout[v] = ++timer;
}
bool is_ancestor(int u, int v)
{
return tin[u] <= tin[v] && tout[u] >= tout[v];
}
int lca(int u, int v)
{
if (is_ancestor(u, v))
return u;
if (is_ancestor(v, u))
return v;
for (int i = l; i >= 0; --i) {
if (!is_ancestor(up[u][i], v))
u = up[u][i];
}
return up[u][0];
}
void preprocess(int root) {
tin.clear();
tin.resize(n);
tout.clear();
tout.resize(n);
timer = 0;
l = ceil(log2(n));
up.clear();
up.assign(n, vector<int>(l + 1));
dfs1(root,root);
}
void bfs(int s){
vector<bool> vis(n,false);
vis[s]=true;
queue<int> q;
q.push(s);
dep[s]=0;
while(q.size()>0){
int u=q.front();
q.pop();
for(auto i:adj[u]){
if(!vis[i]){
dep[i]=dep[u]+1;
vis[i]=true;
q.push(i);
}
}
}
}
int constructST(int ss, int se, int si){
if(ss==se){
tree[si]=0;
return 0;
}
int mid=(ss+se)/2;
tree[si]=constructST(ss,mid,2*si+1)+constructST(mid+1,se,2*si+2);
return tree[si];
}
int getsum(int qs, int qe, int ss, int se, int si){
if(se<qs || ss>qe) return 0;
if(qs<=ss && qe>=se) return tree[si];
int mid=(ss+se)/2;
int v1=getsum(qs,qe,ss,mid,2*si+1);
int v2=getsum(qs,qe,mid+1,se,2*si+2);
return v1+v2;
}
void update(int ss, int se, int i, int si, int diff){
if(i<ss || i>se) return;
tree[si]=tree[si]+diff;
if(se>ss){
int mid=(ss+se)/2;
update(ss,mid,i,2*si+1,diff);
update(mid+1,se,i,2*si+2,diff);
}
}
void dfs2(int x, int p, int& si){
a[x]=si;
si++;
for(auto i:adj[x]){
if(i!=p){
dfs2(i,x,si);
}
}
}
int main(){
fast;
int t;
t=1;
while(t--){
cin>>n;
adj.clear();
adj.resize(n);
vector<pair<int,int>> v1;
for(int i=0;i<n-1;i++){
int u,v;
cin>>u>>v;
u--;
v--;
adj[u].push_back(v);
adj[v].push_back(u);
v1.push_back({u,v});
}
int root=-1;
for(int i=0;i<n;i++) if((int)adj[i].size()>2) root=i;
if(root==-1){
for(int i=0;i<n;i++) if((int)adj[i].size()==1) root=i;
}
dep.clear();
dep.resize(n,0);
preprocess(root);
bfs(root);
sz=0;
a.clear();
a.resize(n,0);
dfs2(root,-1,sz);
tree.clear();
tree.resize(4*sz);
constructST(0,sz-1,0);
int q;
cin>>q;
while(q--){
int type;
cin>>type;
if(type==1){
int ind;
cin>>ind;
ind--;
int u=v1[ind].first,v=v1[ind].second;
if(v==lca(u,v)) swap(u,v);
update(0,sz-1,a[v],0,1);
}
else if(type==2){
int ind;
cin>>ind;
ind--;
int u=v1[ind].first,v=v1[ind].second;
if(v==lca(u,v)) swap(u,v);
update(0,sz-1,a[v],0,-1);
}
else{
int u,v;
cin>>u>>v;
u--;
v--;
int l1=lca(u,v);
int dist1=dep[l1]+dep[u]-2*dep[lca(l1,u)];
int dist2=dep[l1]+dep[v]-2*dep[lca(l1,v)];
int sum1=getsum(a[u]-dist1+1,a[u],0,sz-1,0);
int sum2=getsum(a[v]-dist2+1,a[v],0,sz-1,0);
if((sum1+sum2)==0) cout<<dep[u]+dep[v]-2*dep[lca(u,v)]<<endl;
else cout<<"-1"<<endl;
}
}
}
}
1400C - Binary String Reconstruction | 1734D - Slime Escape |
1499A - Domino on Windowsill | 991A - If at first you don't succeed |
1196C - Robot Breakout | 373A - Collecting Beats is Fun |
965A - Paper Airplanes | 863E - Turn Off The TV |
630E - A rectangle | 1104A - Splitting into digits |
19C - Deletion of Repeats | 1550B - Maximum Cost Deletion |
1693A - Directional Increase | 735D - Taxes |
989A - A Blend of Springtime | 339C - Xenia and Weights |
608A - Saitama Destroys Hotel | 1342C - Yet Another Counting Problem |
548A - Mike and Fax | 109A - Lucky Sum of Digits |
864C - Bus | 626B - Cards |
1221A - 2048 Game | 1374D - Zero Remainder Array |
1567C - Carrying Conundrum | 1029C - Maximal Intersection |
922C - Cave Painting | 811C - Vladik and Memorable Trip |
1589C - Two Arrays | 1510K - King's Task |